export default class AudioPlayer {
  private cache = new Map<string, AudioBuffer>();
  private context: AudioContext;
  private pendingMessions: [string, string][] = [];
  private initialized = false;
  private sourceNode: AudioBufferSourceNode | null;

  constructor() {
    document.addEventListener("click", () => this.init(), { once: true });
  }

  private init() {
    this.initialized = true;
    this.context = new AudioContext();
    while (this.pendingMessions.length) {
      const [id, url] = this.pendingMessions.shift()!;
      this.load(id, url);
    }
  }

  load(id: string, url: string) {
    if (!this.initialized) {
      this.pendingMessions.push([id, url]);
      return;
    }
    fetch(url)
      .then((response) => response.arrayBuffer())
      .then((buffer) => {
        this.context.decodeAudioData(buffer, (audioBuffer) => {
          this.cache.set(id, audioBuffer);
        });
      });
  }

  play(id: string) {
    if (!this.initialized) {
      throw new Error("AudioPlayer is not initialized!");
    }
    console.log("play");
    const sourceNode = this.context.createBufferSource(); // 创建音频源节点
    if (!this.cache.has(id)) {
      console.warn("no data");
      return;
    }
    sourceNode.buffer = this.cache.get(id)!; // 将解码后的音频数据设置到源节点中

    // 创建 MediaStreamAudioSourceNode，将其连接到 AudioContext
    sourceNode.connect(this.context.destination); // 将音频源连接到目标

    sourceNode.start(); // 启动音频源
    this.sourceNode = sourceNode;
    sourceNode.addEventListener("ended", () => {
      this.sourceNode = null;
    });
  }

  stop() {
    if (this.sourceNode) {
      this.sourceNode.stop();
    }
  }
}
